package com.bitoon.basketdudes.ws;
import com.bitoon.basketdudes.jpa.*;
import java.io.PrintWriter;
import java.util.*;
import javax.naming.*;
import javax.persistence.*;

import javax.servlet.http.*;
import org.apache.log4j.*;

/**
 * @author Paco 2012
 */
public class CartasManager {

    Context     initContext = null;
    Context     envContext  = null;
    Logger      log = Logger.getLogger(DatosEquipo.class);

    EntityManagerFactory emfBasket         = null;

    public CartasManager() {
        try {
            // JPA Units
            emfBasket   = PersistenceManager.getInstance().getEntityManagerFactory("jpa_basket");

        } catch (Exception e) {
            log.error("[ERROR][constructor]: No se puedo conectar a la base de datos: " , e);
        }

    }


    public String wsUniformar(HttpServletRequest request, HttpServletResponse response) {
        // Cambia el uniforme a un equipo, gasta la carta de cambio de equipación,
        // comprobando que la carta permite la nueva combinación de camiseta y pantalon
        // Retorno: 101 - No existe la combinación.
        //          102 - El equipo no tiene unidades de la carta.
        //          103 - El equipo no tiene aspecto actual.

        String          retorno = "";
        EntityManager   em = null;
        try {
            int  p_equipo_id   = Integer.parseInt(request.getParameter("equipo_id"));
            int  p_carta_id    = Integer.parseInt(request.getParameter("carta_id"));
            int  p_object_id   = Integer.parseInt(request.getParameter("item_id"));

            // recogemos los colores
            String p_clr1        = request.getParameter("clr1");
            String p_clr2        = request.getParameter("clr2");
            String p_clr3        = request.getParameter("clr3");
            String p_clr21       = request.getParameter("clr21");
            String p_clr22       = request.getParameter("clr22");
            String p_clr23       = request.getParameter("clr23");

            HttpSession miSesion    = request.getSession(true);
            String      sesion_id   = miSesion.getId();

            LoginAction la = new LoginAction();
            em = emfBasket.createEntityManager(); // check 07.08.2012

            em.getTransaction().begin();

            int aux_usuario_id = la.comprobarSesionEquipo(sesion_id,p_equipo_id,em);
            if ( aux_usuario_id <0 ) {
                retorno="error=-10;descripcion=Sesion Incorrecta";
                throw new ExcepcionGeneral( -10, "Sesion Incorrecta " + p_equipo_id + " " + sesion_id);
            } else {

                BuscaCartaEquipo ( em, p_equipo_id, p_carta_id, 11, p_object_id );

                // Buscamos el aspecto actual del equipo
                Query qa = em.createNamedQuery("AspectoEquipo.findByEquipoId");
                qa.setParameter("equipoId" , p_equipo_id);
                List<AspectoEquipo> lista_aspecto = qa.getResultList();
                if (lista_aspecto.isEmpty()) {
                    throw new ExcepcionGeneral( -103, "El equipo no tiene aspecto actualmente " + p_equipo_id );
                }

                //Actualizamos la uniformidad del equipo
                AspectoEquipo aspecto = lista_aspecto.get(0);
                aspecto.setCamiseta ((short)p_object_id);
                aspecto.setClr1     (p_clr1);
                aspecto.setClr2     (p_clr2);
                aspecto.setClr3     (p_clr3);
                aspecto.setClr21    (p_clr21);
                aspecto.setClr22    (p_clr22);
                aspecto.setClr23    (p_clr23);

                // Gastamos la carta
                Cartas cartas=new Cartas();
                cartas.sacarCartaInventario ( em, p_equipo_id, p_carta_id , 1 );

                if ( em != null && em.getTransaction().isActive() )
                    em.getTransaction().commit();

                retorno="error=0;";
            }
        } catch (ExcepcionGeneral ex) {
            log.error("[ERROR][UNIFORMAR1]: " , ex);
            retorno = "error="+ex.getCodigo()+";descripcion="+ex.getDescripion()+ ";";
            if ( em != null && em.getTransaction().isActive() )
                em.getTransaction().rollback();
        } catch (Exception x) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[ERROR][UNIFORMAR2]: ", x);
            retorno = "error=-100";
        } finally {
            try { if (em != null) em.close(); } // revisado 09/08/2012
            catch (Exception e) {
                log.error("[ERROR][constructor]: EMT base de datos: " , e);
            }
        }
        return retorno;
    }

    public String wsQuitarTatuaje(HttpServletRequest request, HttpServletResponse response) {
        // Añade ropa a un jugador en un slot o Cambia la ropa existente en un slot
        // La antigua ropa pasa al inventario en el caso de cambio
        // Se recalculan las caracteristicas del jugador si la ropa afecta a las mismas

        String          retorno = "";
        EntityManager em = null;
        try {
            em = emfBasket.createEntityManager(); // check 07.08.2012

            int                         jugador_id_buscar  = Integer.parseInt(request.getParameter("jugador_id"));
            int                         equipo_id_buscar   = Integer.parseInt(request.getParameter("equipo_id"));
            Hashtable <Short,Integer>   ropa_jugador = new Hashtable();

            HttpSession miSesion = request.getSession(true);
            String idSesion = miSesion.getId();

            LoginAction la = new LoginAction();
            int aux_usuario_id = la.comprobarSesionEquipo(idSesion,equipo_id_buscar,em);
            if ( aux_usuario_id <0 ) {
                log.error("Sesión Incorrecta "+idSesion+" "+equipo_id_buscar+":"+aux_usuario_id);
                retorno="error=-3";
            } else {
                for (short i=1; i< 8;i ++) {
                    ropa_jugador.put ( (short)i, ( request.getParameter("slot"+i) != null ? Integer.parseInt(request.getParameter("slot"+i)) : -1 ) );
                }

                

                Vestidor vestidor = new Vestidor ();
                retorno=vestidor.vestirJugador ( em, jugador_id_buscar, ropa_jugador,3 );
            }
        } catch (ExcepcionGeneral e) {
            log.error("[ERROR][VESTIR1]: " , e);
            retorno = "error="+e.getCodigo()+";descripcion="+e.getDescripion();
        } catch (Exception x) {
            log.error("[ERROR][VESTIR2]: ", x);
            retorno = "error=-100";
        } finally {
            try { em.close(); } catch (Exception e) { } // revisado 09/08/2012
        }
        return retorno;
    }

    public String wsCambiarPelota(HttpServletRequest request, HttpServletResponse response) {
        // Cambia el balón de un equipo, gasta la carta de cambio de balón,
        // comprobando que la carta tiene dicho balón entre los permitidos
        // Retorno: 101 - No existe la combinación.
        //          102 - El equipo no tiene unidades de la carta.
        //          103 - El equipo no tiene aspecto actual.

        String          retorno = "";
        EntityManager   em = null;
        try {
            int  p_equipo_id   = Integer.parseInt(request.getParameter("equipo_id"));
            int  p_carta_id    = Integer.parseInt(request.getParameter("carta_id"));
            int  p_object_id   = Integer.parseInt(request.getParameter("item_id"));

            HttpSession miSesion    = request.getSession(true);
            String      sesion_id   = miSesion.getId();

            LoginAction la = new LoginAction();
            em = emfBasket.createEntityManager(); // check 07.08.2012

            em.getTransaction().begin();

            int aux_usuario_id = la.comprobarSesionEquipo(sesion_id,p_equipo_id,em);
            if ( aux_usuario_id <0 ) {
                retorno="error=-10;descripcion=Sesion Incorrecta";
                throw new ExcepcionGeneral( -10, "Sesion Incorrecta " + p_equipo_id + " " + sesion_id);
            }
            {
                BuscaCartaEquipo ( em, p_equipo_id, p_carta_id, 12, p_object_id );

                // Buscamos el aspecto actual del equipo
                Query qa = em.createNamedQuery("AspectoEquipo.findByEquipoId");
                qa.setParameter("equipoId" , p_equipo_id);
                List<AspectoEquipo> lista_aspecto = qa.getResultList();
                if (lista_aspecto.isEmpty()) {
                    throw new ExcepcionGeneral( -103, "El equipo no tiene aspecto actualmente " + p_equipo_id );
                }

                //Actualizamos la uniformidad del equipo
                AspectoEquipo aspecto = lista_aspecto.get(0);
                aspecto.setBallId    (p_object_id);

                // Gastamos la carta
                Cartas cartas=new Cartas();
                cartas.sacarCartaInventario ( em, p_equipo_id, p_carta_id , 1 );

                if ( em != null && em.getTransaction().isActive() )
                    em.getTransaction().commit();

                retorno="error=0;";
            }
        } catch (ExcepcionGeneral ex) {
            log.error("[ERROR][UNIFORMAR1]: " , ex);
            retorno = "error="+ex.getCodigo()+";descripcion="+ex.getDescripion()+ ";";
            if ( em != null && em.getTransaction().isActive() )
                em.getTransaction().rollback();
        } catch (Exception x) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[ERROR][UNIFORMAR2]: ", x);
            retorno = "error=-100";
        } finally {
            try { if (em != null) em.close(); } // revisado 09/08/2012
            catch (Exception e) {
                log.error("[ERROR][constructor]: EMT base de datos: " , e);
            }
        }
        return retorno;
    }




    public void BuscaCartaEquipo ( EntityManager em, int p_equipo_id, int p_carta_id,
                                   int p_tipo, int p_object_id ) throws ExcepcionGeneral
    {
        // Buscamos la combinación carta_id, object_type y object_id
        Query qc = em.createNamedQuery("CartaObjeto.findCombinacion");
        qc.setParameter("carta_id"  , p_carta_id);
        qc.setParameter("object_type" , p_tipo  ); // 11 - uniforme, 12 - balon
        qc.setParameter("object_id" , p_object_id);
        List<CartaObjeto> lista_carta = qc.getResultList();
        if (lista_carta.isEmpty()) {
            throw new ExcepcionGeneral( -101, "No existe la combinación " + p_carta_id + " " +p_object_id );
        }

        // Buscamos que el equipo tenga la carta
        CartaEquipo carta_equipo = Util.BuscarCartaEquipo( em, p_equipo_id, p_carta_id );
        if ( carta_equipo == null) {
            throw new ExcepcionGeneral( -102, "El equipo no tiene unidades suficientes de la carta " + p_equipo_id +" "+p_carta_id);
        }
    }

    public String wsTalentoQuitar(HttpServletRequest request, HttpServletResponse response) {
        // Borra el talento asociado a un jugador
        // Retorno: -10 - Sesión Incorrecta
        //           -3 - No tienes la carta
        //          -101 - El jugador no tiene ese talento.
        //          -102 - No existe el jugador

        String          retorno     = "";
        EntityManager   em          = null;
        Jugador         jugador     = null;
        Boolean         encontrado  = false;
        int             p_equipo_id;
        short           p_talento_id=0;
        try {
            int    p_jugador_id   = Integer.parseInt(request.getParameter("jugador_id"));
                   p_equipo_id    = Integer.parseInt(request.getParameter("equipo_id"));
                   p_talento_id   = Short.parseShort(request.getParameter("talento_id"));

            HttpSession miSesion    = request.getSession(true);
            String      sesion_id   = miSesion.getId();

            LoginAction la = new LoginAction();
            em = emfBasket.createEntityManager(); // check 07.08.2012

            em.getTransaction().begin();

            int aux_usuario_id = la.comprobarSesionEquipo(sesion_id,p_equipo_id,em);
            if ( aux_usuario_id <0 ) {
                retorno="error=-10;descripcion=Sesion Incorrecta";
                throw new ExcepcionGeneral( -10, "Sesion Incorrecta " + p_equipo_id + " " + sesion_id);
            }


            // Buscamos el aspecto actual del equipo
            Query qa = em.createNamedQuery("Jugador.findById");
            qa.setParameter("id" , p_jugador_id );
            jugador = (Jugador)qa.getSingleResult();
            if ( jugador == null ) {
                throw new ExcepcionGeneral( -102, "Player not found " + p_jugador_id );
            }

            if ( jugador.getEquipo().getId() != p_equipo_id) {
                throw new ExcepcionGeneral( -103, "Player of another team " + p_jugador_id );
            }

            if ( jugador.getTalento1() == p_talento_id ) {
                jugador.setTalento1( (short)0 );
                encontrado = true;
            }
            if ( jugador.getTalento2() == p_talento_id ) {
                jugador.setTalento2( (short)0 );
                encontrado = true;
            }
            if ( jugador.getTalento3() == p_talento_id ) {
                jugador.setTalento3( (short)0 );
                encontrado = true;
            }

            if ( !encontrado || p_talento_id < 1 ) {
                throw new ExcepcionGeneral( -101, "Talent not found " + p_jugador_id );
            }

            // Gastamos la carta
            Cartas cartas=new Cartas();
            cartas.sacarCartaInventario ( em, p_equipo_id, 10009 , 1 );

            if ( em != null && em.getTransaction().isActive() )
                em.getTransaction().commit();

            retorno="error=0;t1="+jugador.getTalento1()+";t2="+jugador.getTalento2()+";t3="+jugador.getTalento3()+";";

        } catch (ExcepcionGeneral ex) {
            log.error("[ERROR][TALENTOQUITAR]: " , ex);
            retorno = "error="+ex.getCodigo()+";descripcion="+ex.getDescripion()+ ";";
            if ( em != null && em.getTransaction().isActive() )
                em.getTransaction().rollback();
        } catch (Exception x) {
            try { em.getTransaction().rollback(); } catch (Exception e2) { }
            log.error("[ERROR][TALENTOQUITAR]: ", x);
            retorno = "error=-100";
        } finally {
            try { if (em != null) em.close(); } // revisado 09/08/2012
            catch (Exception e) {
                log.error("[ERROR][constructor]: EMT base de datos: " , e);
            }
        }
        try {
            PrintWriter out = response.getWriter();
            out.print(retorno);
        } catch (Exception e) {
            log.error("[PrintWriter]: " , e);
        }
        return retorno;
    }

    // Gasta una carta de un equipo
    // Puede lanzar la excepcion -16 The team doesn't have the card
    public void gastarCarta ( EntityManager p_em, Equipo p_equipo, int p_carta_id ) throws ExcepcionGeneral{

        CartaEquipo carta_equipo = Util.BuscarCartaEquipo( p_em, p_equipo.getId(), p_carta_id );

        if (carta_equipo == null)
            throw new ExcepcionGeneral( -102, "The team doesn't have the card"  );

        Cartas cartas = new Cartas();
        cartas.sacarCartaInventario ( p_em, p_equipo.getId(), p_carta_id , 1 );
    }


}
